package de.fstyle.android.location.startstop;

import java.util.Locale;

import android.app.Activity;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.Toast;
import de.fstyle.android.location.LayoutHelper;
import de.fstyle.android.location.MainActivity;
import de.fstyle.android.location.R;
import de.fstyle.android.location.UpdateLocationListener;

public abstract class AbstractStartStopActivity extends Activity {

	public final String LOG_TAG = this.getClass().getSimpleName();
	
	public static final int LIMIT = 10;
	
	private LocationManager locationManager;
	private UpdateLocationListener locationListener;
	
	public abstract String getProvider();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {

		Log.d(LOG_TAG, "creating activity for provider: " + this.getProvider());
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_startstop);
		
		// set title
		
		this.setTitle(this.getProvider().toUpperCase(Locale.US));
		
		// get location manager
		
		Log.d(LOG_TAG, "getting location manager");
		
		this.locationManager = 
				(LocationManager) this.getSystemService(LOCATION_SERVICE);
		
		// get location listener
		
		Log.d(LOG_TAG, "getting location listener for provider: " + this.getProvider());
		
		if (getProvider().equals(LocationManager.GPS_PROVIDER)) {
			this.locationListener = MainActivity.GPS_LISTENER;
		} else if (getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
			this.locationListener = MainActivity.NETWORK_LISTENER;
		} else if (getProvider().equals(LocationManager.PASSIVE_PROVIDER)) {
			this.locationListener = MainActivity.PASSIVE_LISTENER;
		}
		
		
	
		Log.d(LOG_TAG, "configuring location listener: " + this.getProvider());
		this.locationListener.setActivity(this);
		
		try {
			this.locationManager.getLastKnownLocation(this.getProvider());
		} catch (IllegalArgumentException e) {
			message("location provider does not exist");
		}
		
		if (!this.locationManager.isProviderEnabled(this.getProvider())) {
			message("location provider is disabled");
		}
	}
	
	@Override
	protected void onPause() {
		Log.d(LOG_TAG, "pause: " + this.getProvider());
		super.onPause();
		this.locationListener.setActivity(null);
	}
	
	public void add(Location location) {
		Log.d(LOG_TAG, "adding location for provider: " + this.getProvider());
		
		LinearLayout linearLayout = 
				(LinearLayout) findViewById(R.id.gps_list);
		
		TableLayout tableLayout = 
				LayoutHelper.createTable(null, AbstractStartStopActivity.this);
		linearLayout.addView(tableLayout, 0);
		
		LayoutHelper.updateRow(tableLayout, location, false);
		
		int count = linearLayout.getChildCount();
		if (count > LIMIT) {
			Log.d(LOG_TAG, "limit reached: removing last entry");
			linearLayout.removeViewAt(count - 1);
		}
	}
	
	public void message(String message) {
		Log.d(LOG_TAG, "message: " + message);
		LinearLayout linearLayout = 
				(LinearLayout) findViewById(R.id.gps_list);
		
		TableLayout tableLayout = 
				LayoutHelper.createTable(null, AbstractStartStopActivity.this);
		tableLayout.setBackgroundColor(Color.RED);
		tableLayout.setPadding(10, 10, 10, 10);
		linearLayout.addView(tableLayout, 0);
		
		LayoutHelper.messageRow(tableLayout, message);
	}
	
	public void stopLocationUpdate() {
		
		Log.d(LOG_TAG, "stoping location update: " + this.getProvider());
		
		this.locationManager.removeUpdates(this.locationListener);
		this.locationListener.setRunning(false);
		Toast toast = Toast.makeText(
				AbstractStartStopActivity.this, 
				"Provider stopped: " + this.getProvider(), 
				Toast.LENGTH_SHORT);
		toast.show();
	}

	public void startLocationUpdate() {
		
		Log.d(LOG_TAG, "starting location update: " + this.getProvider());
		
		try {
			if (!this.locationListener.isRunning()) {
				
				EditText intervalInput = (EditText) this.findViewById(R.id.gps_interval);
				String intervalString = intervalInput.getText().toString();
				intervalString = intervalString.equals("") ? "0" : intervalString;
				int interval;
				try {
					interval = Integer.parseInt(intervalString);
				} catch (NumberFormatException e) {
					Toast toast = Toast.makeText(
							AbstractStartStopActivity.this, 
							"Invalid interval: " + intervalString, 
							Toast.LENGTH_SHORT);
					toast.show();
					return;
				}
				
				EditText distanceInput = (EditText) this.findViewById(R.id.gps_distance);
				String distanceString = distanceInput.getText().toString();
				distanceString = distanceString.equals("") ? "0" : distanceString;
				int distance;
				try {
					distance = Integer.parseInt(distanceString);
				} catch (NumberFormatException e) {
					Toast toast = Toast.makeText(
							AbstractStartStopActivity.this, 
							"Invalid distance: " + distanceString, 
							Toast.LENGTH_SHORT);
					toast.show();
					return;
				}
				
				this.locationManager.requestLocationUpdates(
						getProvider(), 
						interval,
						distance,
						this.locationListener);
				this.locationListener.setRunning(true);
				Toast toast = Toast.makeText(
						AbstractStartStopActivity.this, 
						"Provider started: " + this.getProvider() + "\n" +
						"Interval: " + interval + " ms\n" +
						"Distance: " + distance + " m", 
						Toast.LENGTH_SHORT);
				toast.show();
			} else {
				Toast toast = Toast.makeText(
						AbstractStartStopActivity.this, 
						"Already started: " + this.getProvider(), 
						Toast.LENGTH_SHORT);
				toast.show();
			}
		} catch(IllegalArgumentException e) {
			Log.d(LOG_TAG, "location provider does not exist: " + this.getProvider());
			message("location provider does not exist");
		}
	}
	
	public void onActionStart(View view) {
		Log.d(LOG_TAG, "button: start");
		this.startLocationUpdate();
	}
	
	public void onActionStop(View view) {
		Log.d(LOG_TAG, "button: stop");
		this.stopLocationUpdate();
	}
	
}
